package com.zhu.ttwords.common;

/**
 * 1. Split the knowledge into smallest possible items.
 * 2. With all items associate an E-Factor equal to 2.5.
 * 3. Repeat items using the following intervals:
 * I(1):=1
 * I(2):=6
 * for n>2: I(n):=I(n-1)*EF
 * where:
 * I(n) - inter-repetition interval after the n-th repetition (in days),
 * EF - E-Factor of a given item
 * If interval is a fraction, round it up to the nearest integer.
 * 4. After each repetition assess the quality of repetition response in 0-5 grade scale:
 * 5 - perfect response
 * 4 - correct response after a hesitation
 * 3 - correct response recalled with serious difficulty
 * 2 - incorrect response; where the correct one seemed easy to recall
 * 1 - incorrect response; the correct one remembered
 * 0 - complete blackout.
 * 5. After each repetition modify the E-Factor of the recently repeated item according to the formula:
 * EF':=EF+(0.1-(5-q)*(0.08+(5-q)*0.02))
 * EF':=EF-0.8+0.28*q-0.02*q*q
 * where:
 * EF' - new value of the E-Factor,
 * EF - old value of the E-Factor,
 * q - quality of the response in the 0-5 grade scale.
 * If EF is less than 1.3 then let EF be 1.3.
 * 6. If the quality response was lower than 3 then start repetitions for the item from the
 * beginning without changing the E-Factor (i.e. use intervals I(1), I(2) etc. as if the item was memorized anew).
 * 7. After each repetition session of a given day repeat again all items that scored below four in the quality assessment.
 * Continue the repetitions until all of these items score at least four.
 * <p/>
 * q状态 0-2重置状态。I(n)为1
 * 3 减少
 * 4 ef不变
 * 5 增加
 * <p/>
 * n I(n) EF q
 */
public class SuperMeMoUtil {

    /**
     * SuperMemo算法计算下一次复习间隔天数
     * @param day 上一次间隔的天数
     * @param ef  难度系数E-Factor
     * @param n   第几次测试
     * @return
     */
    public static int getDay(int day, float ef, int n) {
        if (n == 1) {
            return 1;
        } else if (n == 2) {
            return 6;
        } else {
            return (int) Math.ceil(day * ef);
        }
    }

    public static float getEM(float Ef, int q) {
        float EF = Ef + (0.1f - (5f - q) * (0.08f + (5f - q) * 0.02f));
        if (EF <= 1.3f) {
            EF = 1.3f;
        } else if (EF >= 2.5f) {
            EF = 2.5f;
        }
        return EF;
    }
}
